//package vip.wangwenhao.sso.config.security.filter;
//
//import org.springframework.security.authentication.AnonymousAuthenticationToken;
//import org.springframework.security.authentication.AuthenticationDetailsSource;
//import org.springframework.security.authentication.AuthenticationManager;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.AuthenticationException;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.security.web.AuthenticationEntryPoint;
//import org.springframework.security.web.authentication.NullRememberMeServices;
//import org.springframework.security.web.authentication.RememberMeServices;
//import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
//import org.springframework.util.Assert;
//import org.springframework.util.StringUtils;
//import org.springframework.web.filter.OncePerRequestFilter;
//import vip.wangwenhao.common.enums.ResultCode;
//import vip.wangwenhao.common.result.Result;
//import vip.wangwenhao.common.util.HttpUtils;
//import vip.wangwenhao.common.util.Oauth2Utils;
//import vip.wangwenhao.sso.api.pojo.CustomAuthenticationToken;
//
//import javax.servlet.FilterChain;
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//
//public class TokenAuthenticationFilter extends OncePerRequestFilter {
//
//    private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
//    private AuthenticationEntryPoint authenticationEntryPoint;
//    private AuthenticationManager authenticationManager;
//    private RememberMeServices rememberMeServices = new NullRememberMeServices();
//    private boolean ignoreFailure = false;
//
//
//    public TokenAuthenticationFilter(AuthenticationManager authenticationManager,
//                                     AuthenticationEntryPoint authenticationEntryPoint) {
//        Assert.notNull(authenticationManager, "authenticationManager cannot be null");
//        Assert.notNull(authenticationEntryPoint, "authenticationEntryPoint cannot be null");
//        this.authenticationManager = authenticationManager;
//        this.authenticationEntryPoint = authenticationEntryPoint;
//    }
//
//    @Override
//    public void afterPropertiesSet() {
//        Assert.notNull(this.authenticationManager, "An AuthenticationManager is required");
//
//        if (!isIgnoreFailure()) {
//            Assert.notNull(this.authenticationEntryPoint, "An AuthenticationEntryPoint is required");
//        }
//    }
//
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
//            throws IOException, ServletException {
//        final boolean debug = logger.isDebugEnabled();
//
//        try {
//
//
//            String token = Oauth2Utils.getToken(request);
//
//            if (debug) {
//                logger.debug("Token Authentication Authorization header found for token '" + token + "'");
//            }
//
//            if (authenticationIsRequired(token)) {
//                CustomAuthenticationToken authRequest = new CustomAuthenticationToken(token);
//                authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
//                Authentication authResult = authenticationManager.authenticate(authRequest);
//
//                if (debug) {
//                    logger.debug("Authentication success: " + authResult);
//                }
//
//                SecurityContextHolder.getContext().setAuthentication(authResult);
//
//                rememberMeServices.loginSuccess(request, response, authResult);
//
//                onSuccessfulAuthentication(request, response, authResult);
//            }
//
//        } catch (AuthenticationException failed) {
//            if (debug) {
//                logger.debug("Authentication request for failed: " + failed);
//            }
//
//            rememberMeServices.loginFail(request, response);
//
//            onUnsuccessfulAuthentication(request, response, failed);
//
//            if (ignoreFailure) {
//                chain.doFilter(request, response);
//            } else {
//                logger.info("authenticationEntryPoint:" + authenticationEntryPoint);
//                authenticationEntryPoint.commence(request, response, failed);
//            }
//        }
//
//        chain.doFilter(request, response);
//    }
//
//
//    /**
//     * 判断是否需要登录
//     *
//     * @param token
//     * @return
//     */
//    private boolean authenticationIsRequired(String token) {
//
//        Authentication existingAuth = SecurityContextHolder.getContext().getAuthentication();
//
//        logger.info("existingAuth:" + existingAuth);
//
//        if (StringUtils.isEmpty(token)) {
//            return false;
//        }
//
//        if (existingAuth == null || !existingAuth.isAuthenticated()) {
//            return true;
//        }
//
//        if (existingAuth instanceof CustomAuthenticationToken && !existingAuth.getName().equals(token)) {
//            return true;
//        }
//
//        if (existingAuth instanceof AnonymousAuthenticationToken) {
//            return true;
//        }
//
//        return false;
//    }
//
//    protected void onSuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
//                                              Authentication authResult) throws IOException {
//
//    }
//
//    protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
//                                                AuthenticationException failed) throws IOException {
//        logger.info("用户验证失败");
//        HttpUtils.response(response, org.apache.http.HttpStatus.SC_OK, Result.fail(ResultCode.AUTHORIZATION_INVALID));
//    }
//
//    protected AuthenticationEntryPoint getAuthenticationEntryPoint() {
//        return authenticationEntryPoint;
//    }
//
//    protected AuthenticationManager getAuthenticationManager() {
//        return authenticationManager;
//    }
//
//    protected boolean isIgnoreFailure() {
//        return ignoreFailure;
//    }
//
//    public void setAuthenticationDetailsSource(
//            AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
//        Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
//        this.authenticationDetailsSource = authenticationDetailsSource;
//    }
//
//    public void setRememberMeServices(RememberMeServices rememberMeServices) {
//        Assert.notNull(rememberMeServices, "rememberMeServices cannot be null");
//        this.rememberMeServices = rememberMeServices;
//    }
//}